//
//  TableViewUtils.swift
//  novelReader
//
//  Created by Ink on 2019/9/12.
//  Copyright © 2019 ChineseAll. All rights reserved.
//

public protocol RegisterCellProtocol: NSObjectProtocol{
    
    associatedtype CType
    
    func register(_ cellType: CType.Type)
    func registerNib(_ cellType: CType.Type)
}

public protocol RegisterHeaderFooterProtocol: NSObjectProtocol{
    
    associatedtype HFType
    
    func registerHeaderFooterView(_ type: HFType.Type)
    func registerHeaderFooterViewNib(_ type: HFType.Type)
}

extension UITableView: RegisterCellProtocol {
    
    public typealias CType = UITableViewCell
    
    public final func register<T: CType>(_ cellType: T.Type) {
        register(cellType, forCellReuseIdentifier: T.reuseIdentifier)
    }
    
    public final func registerNib<T: CType>(_ cellType: T.Type) {
        register(T.nib, forCellReuseIdentifier: T.reuseIdentifier)
    }
}

extension UITableView: RegisterHeaderFooterProtocol {
    
    public typealias HFType = UITableViewHeaderFooterView
    
    // MARK: - register
    public final func registerHeaderFooterView<T: HFType>(_ type: T.Type) {
        register(type, forHeaderFooterViewReuseIdentifier: T.reuseIdentifier)
    }
    
    public final func registerHeaderFooterViewNib<T: HFType>(_ type: T.Type) {
        register(T.nib, forHeaderFooterViewReuseIdentifier: T.reuseIdentifier)
    }
}


extension UITableView {
    
    // MARK: - dequeueReusable
    
    // use it ,must be registered
    public func dequeueReusableCell<T : CType>(for indexPath: IndexPath) -> T {
        dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as? T ?? T.init()
    }
    
    public func dequeueReusableCell<T : CType>(withStyle style: T.CellStyle = .default) -> T {
        (dequeueReusableCell(withIdentifier: T.reuseIdentifier) as? T) ??  T(style: style, reuseIdentifier: T.reuseIdentifier)
    }
    
    public func dequeueReusableHeaderFooterView<T : HFType>() -> T {
        (dequeueReusableHeaderFooterView(withIdentifier: T.reuseIdentifier) as? T) ??  T(reuseIdentifier: T.reuseIdentifier)
    }
    
}

public protocol CellHeightProtocol: ViewSizeProtocol {}

public extension CellHeightProtocol {
     static var viewHeight: CGFloat { UITableView.automaticDimension }
}

extension UITableViewCell: CellHeightProtocol {}

public extension UITableView {
    
    func cornerRadius(_ cell: UITableViewCell, indexPath: IndexPath, cornerRadius: CGFloat) {
        
        let sectionCount = numberOfRows(inSection: indexPath.section)
                
        if sectionCount > 0 {
            var corners = UIRectCorner()
            
            if indexPath.row == 0 {
                corners.formUnion([.topLeft, .topRight])
            }
            if indexPath.row == sectionCount - 1 {
                corners.formUnion([.bottomLeft, .bottomRight])
            }
            if !corners.isEmpty {
                cell.corner(corners, radii: cornerRadius)
            }
            else {
                cell.layer.mask = nil
            }
        }
    }
}

public extension UITableView {
    func scrollToTop(animated: Bool = true) {
        let offset = CGPoint(x: 0, y: -self.adjustedContentInset.top)
        self.setContentOffset(offset, animated: animated)
    }
}

public extension UITableView {
    /// 动态插入缺失的数据行（按原始顺序补全）
    /// - Parameters:
    ///   - partialData: 初始部分数据
    ///   - fullData: 完整数据
    @discardableResult
    func insertMissingRows<T:Equatable>(initialData partialData: [T], fullData: [T]) -> Bool {
        guard partialData.count < fullData.count else { return false }
        
        var indexPaths = [IndexPath]()
        for (index, item) in fullData.enumerated() {
            if !partialData.contains(where:{ $0 == item }) {
                indexPaths.append(IndexPath(row: index, section: 0))
            }
        }
        if indexPaths.isEmpty { return false}
        beginUpdates()
        insertRows(at: indexPaths, with: .none)
        endUpdates()
        return true
    }
}
